#include <cstdlib>
#include <cstring>
#include <iostream>
#include <mutex>

#include "log/logger.h"
#include "os_memery_manager.h"
#include "tlsf/tlsf.h"

// 静态成员初始化
std::atomic<os_memery_manager_t*> os_memery_manager_t::m_instance{ nullptr };
std::mutex os_memery_manager_t::m_mutex;

os_memery_manager_t::os_memery_manager_t() :
    m_pool(nullptr),
    m_pool_size(0),
    m_allocated_blocks(nullptr),
    m_total_allocated(0),
    m_total_deallocated(0),
    m_current_allocated(0),
    m_peak_allocated(0)
{
}
void os_memery_manager_t::init()
{
    m_pool = nullptr;
    m_pool_size = 0;
    m_allocated_blocks = nullptr;
    m_total_allocated = 0;
    m_total_deallocated = 0;
    m_current_allocated = 0;
    m_peak_allocated = 0;
    const size_t DEFAULT_POOL_SIZE = 64 * 1024 * 1024;  // 64MB

    // 允许通过环境变量自定义池大小
    const char* pool_size_env = std::getenv("OS_MEMERY_POOL_SIZE");
    m_pool_size = DEFAULT_POOL_SIZE;

    if (pool_size_env) {
        try {
            m_pool_size = std::stoul(pool_size_env);
        } catch (...) {
            std::cout << "Invalid TLSF_POOL_SIZE, using default: " << DEFAULT_POOL_SIZE << std::endl;
        }
    }
    m_pool = malloc(m_pool_size);
    if (m_pool) {
        tlsf_create_with_pool(m_pool, m_pool_size);
        // LOGI("TLSF内存池初始化成功");
        std::cout << "TLSF内存池初始化成功" << std::endl;
    } else {
        // LOGE("TLSF内存池初始化失败");
        std::cout << "TLSF内存池初始化失败" << std::endl;
    }
}
os_memery_manager_t::~os_memery_manager_t()
{
    if (m_pool) {
        tlsf_destroy(m_pool);
        free(m_pool);
    }
}

os_memery_manager_t* os_memery_manager_t::get_instance()
{
    os_memery_manager_t* tmp = m_instance.load(std::memory_order_acquire);
    if (!tmp) {
        std::lock_guard<std::mutex> lock(m_mutex);
        tmp = m_instance.load(std::memory_order_relaxed);
        if (!tmp) {
            tmp = (os_memery_manager_t*)malloc(sizeof(os_memery_manager_t));
            tmp->init();
            m_instance.store(tmp, std::memory_order_release);
        }
    }
    return tmp;
}

void os_memery_manager_t::destroy()
{
    os_memery_manager_t* tmp = m_instance.load(std::memory_order_acquire);
    if (tmp) {
        m_mutex.lock();
        tmp = m_instance.load(std::memory_order_relaxed);
        m_mutex.unlock();
        if (tmp) {
            tmp->print_leak_report();
            tmp->~os_memery_manager_t();
            free(tmp);
            m_mutex.lock();
            m_instance.store(nullptr, std::memory_order_release);
            m_mutex.unlock();
        }
    }
}

void* os_memery_manager_t::allocate(size_t size, const char* file, int line)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    // 分配额外空间存储头部信息
    size_t total_size = size + sizeof(memory_header_t);
    void* raw_memory = tlsf_malloc(m_pool, total_size);

    if (!raw_memory) {
        return nullptr;
    }
    // 设置头部信息
    memory_header_t* header = static_cast<memory_header_t*>(raw_memory);
    header->magic = MEMORY_MAGIC;
    header->size = size;
    header->file = file;
    header->line = line;

    // 添加到已分配块链表
    header->next = m_allocated_blocks;
    header->prev = nullptr;
    if (m_allocated_blocks) {
        m_allocated_blocks->prev = header;
    }
    m_allocated_blocks = header;

    // 更新统计信息
    // std::cout << "new:" << size << "m_current_allocated:" << m_current_allocated
    //           << "peak_allocated:" << m_peak_allocated << std::endl;
    m_total_allocated++;
    m_current_allocated += size;

    if (m_current_allocated > m_peak_allocated) {
        m_peak_allocated = m_current_allocated;
    }

    // 返回用户数据指针
    return static_cast<char*>(raw_memory) + sizeof(memory_header_t);
}

void os_memery_manager_t::deallocate(void* ptr)
{
    if (!ptr) {
        return;
    }
    std::lock_guard<std::mutex> lock(m_mutex);

    // 获取头部信息
    memory_header_t* header = reinterpret_cast<memory_header_t*>(static_cast<char*>(ptr) - sizeof(memory_header_t));
    if (header->magic != MEMORY_MAGIC) {
        // std::cout<<"delete memory error,not use os_memery_manager"<<std::endl;
        std::free(ptr);
        return;
    }
    header->magic = 0;
    // 从已分配块链表中移除
    if (header->prev) {
        header->prev->next = header->next;
    } else {
        m_allocated_blocks = header->next;
    }
    if (header->next) {
        header->next->prev = header->prev;
    }
    // 更新统计信息
    m_total_deallocated++;
    m_current_allocated -= header->size;

    // 释放内存
    tlsf_free(m_pool, header);
}
size_t os_memery_manager_t::get_current_allocated() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_current_allocated;
}
// 峰值内存分配
size_t os_memery_manager_t::get_peak_allocated() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_peak_allocated;
}
// 总内存分配
size_t os_memery_manager_t::get_total_allocated() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_total_allocated;
}
// 总内存释放量
size_t os_memery_manager_t::get_total_deallocated() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_total_deallocated;
}
size_t os_memery_manager_t::get_total_memory() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_pool_size;
}
size_t os_memery_manager_t::get_remaining_memory() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_pool_size - m_current_allocated;
}
void os_memery_manager_t::print_leak_report()
{
    std::lock_guard<std::mutex> lock(m_mutex);

    std::cout << "==================== Memory Leak Report =====================" << std::endl;
    std::cout << "Total memory(byte)       : " << m_pool_size << std::endl;
    std::cout << "Remaining memory(byte)   : " << m_pool_size - m_current_allocated << std::endl;
    std::cout << "Total allocated(times)   : " << m_total_allocated << std::endl;
    std::cout << "Total deallocated(times) : " << m_total_deallocated << std::endl;
    std::cout << "Current allocated(byte)  : " << m_current_allocated << std::endl;
    std::cout << "Peak allocated(byte)     : " << m_peak_allocated << std::endl;

    if (m_allocated_blocks) {
        std::cout << "\nLeaked blocks:" << std::endl;
        memory_header_t* current = m_allocated_blocks;
        while (current) {
            std::cout << "  Leak at " << (current->file ? current->file : "unknown") << ":" << current->line
                      << " Size: " << current->size << " bytes" << std::endl;
            current = current->next;
        }
    } else {
        std::cout << "No memory leaks detected." << std::endl;
    }
    std::cout << "=============================================================" << std::endl;
}

// 全局访问函数
os_memery_manager_t* get_memery_manager()
{
    return os_memery_manager_t::get_instance();
}

void print_memory_leak_report()
{
    os_memery_manager_t::get_instance()->print_leak_report();
}
// __attribute__((constructor(101), used)) void init_tlsf_allocator()
// __attribute__((section(".init.000"), constructor(101), used))
// void init_tlsf_allocator()
// {
//     std::cout << "init tlsf allocator" << std::endl;
//     os_memery_manager_t::get_instance()->init();
// }
// 程序退出时清理
__attribute__((destructor(65535), used)) void cleanup_tlsf_allocator()
{
    std::cout << "deinit tlsf allocator" << std::endl;
    os_memery_manager_t::destroy();
    std::cout << "deinit tlsf allocator end" << std::endl;
}
